/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package savingloadingkeys;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.SecureRandom;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.crypto.BadPaddingException;

/**
 *
 * @author Maciek
 */
public class SavingLoadingKeys {

    /**
     * @param args the command line arguments
     */
    
    private static String path="";
    private static CypherModel model = new CypherModel();
    private static String password = "bskbsk";
    
    public static void main(String[] args) {
       try {
          
           int keySize = 1024;
           KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
 
            keyGen.initialize(keySize, new SecureRandom());
            KeyPair keyPair = keyGen.genKeyPair();

            System.out.println("Generated Key Pair");
            RSAPrivateKey privKey = (RSAPrivateKey)keyPair.getPrivate();
            
            RSAPublicKey pubKey = (RSAPublicKey)keyPair.getPublic();
            dumpKeyPair(keyPair);
            saveKeyPair(path, keyPair);
            
            KeyPair loadedKeyPair = loadKeyPair(path, "RSA");
            System.out.println("Loaded Key Pair");
            dumpKeyPair(loadedKeyPair);
            
            System.out.println("Sprawdzam czy się sobie równają ");
            RSAPrivateKey newPrivKey = (RSAPrivateKey)loadedKeyPair.getPrivate();
            RSAPublicKey newPubKey = (RSAPublicKey) loadedKeyPair.getPublic();
            System.out.println("newPrivKey == privKey is " +privKey.equals(newPrivKey));
            System.out.println("newPubKey == pubKey is " + pubKey.equals(newPubKey));
           
       
            
            } catch (Exception e) {
            e.printStackTrace();
            return;
            }
    }

    private static void saveKeyPair(String path, KeyPair keyPair) throws FileNotFoundException, IOException {
        RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
        RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();

        // Store Public Key.
        X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(
        publicKey.getEncoded());
        FileOutputStream fos = new FileOutputStream(path + "public.key");
        fos.write(x509EncodedKeySpec.getEncoded());
        fos.close();

        // Store Private Key.
        PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(privateKey.getEncoded());
        System.out.println("PKCS8 " + pkcs8EncodedKeySpec);
        try {
            model.write(pkcs8EncodedKeySpec.getEncoded(), path + "private.key", password);
        } catch (BadPaddingException ex) {
            Logger.getLogger(SavingLoadingKeys.class.getName()).log(Level.SEVERE, null, ex);
        }
        
    }

    private static void dumpKeyPair(KeyPair keyPair) {
        RSAPublicKey pub = (RSAPublicKey) keyPair.getPublic();
        System.out.println("Public Key: " + getHexString(pub.getEncoded()));
 
        RSAPrivateKey priv = (RSAPrivateKey) keyPair.getPrivate();
        System.out.println("Private Key: " + getHexString(priv.getEncoded()));
    }
 
    private static String getHexString(byte[] b) {
        String result = "";
        for (int i = 0; i < b.length; i++) {
          result += Integer.toString((b[i] & 0xff) + 0x100, 16).substring(1);
         }
         return result;
       }

    private static KeyPair loadKeyPair(String path, String string) throws FileNotFoundException, IOException, NoSuchAlgorithmException, InvalidKeySpecException, BadPaddingException {
                    // Read Public Key.
            File filePublicKey = new File(path + "public.key");
            FileInputStream fis = new FileInputStream(path + "public.key");
            byte[] encodedPublicKey = new byte[(int) filePublicKey.length()];
            fis.read(encodedPublicKey);
            fis.close();

            // Read Private Key.
         /*   File filePrivateKey = new File(path + "private.key");
            fis = new FileInputStream(path + "private.key");
            byte[] encodedPrivateKey = new byte[(int) filePrivateKey.length()];
            fis.read(encodedPrivateKey);
            fis.close();*/
            
            byte[] encodedPrivateKey = model.load(path + "private.key", password);

            // Generate KeyPair.
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(
            encodedPublicKey);
            RSAPublicKey publicKey = (RSAPublicKey) keyFactory.generatePublic(publicKeySpec);

            PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(
            encodedPrivateKey);
            RSAPrivateKey privateKey = (RSAPrivateKey) keyFactory.generatePrivate(privateKeySpec);

            return new KeyPair(publicKey, privateKey);
    }
}
